<script lang="ts" setup>
import { onShow } from '@dcloudio/uni-app';
import { getGoodDetailByIdAPI } from '@/apis/good';
import { ref } from 'vue';
import { GoodsResult } from '@/types/good';
import AddressPanel from './components/AddressPanel.vue';
import ServicePanel from './components/ServicePanel.vue';
import GoodSkeleton from './good.skeleton.vue';
import { useSkuPopup } from '@/composables/useSkuPopup';
import { SkuPopupEvent } from '@/types/vk-data-goods-sku-popup';
import { postCartAPI } from '@/apis/cart';
import { useGoodPopup } from './composables/useGoodPopup';
import { useMemberStore } from '@/stores/modules/memberStore';
import { useAddressStore } from '@/stores/modules/addressStore';

// 获取安全距离
const { safeAreaInsets } = uni.getSystemInfoSync();

const memberStore = useMemberStore();
const addressStore = useAddressStore();

// 采用sku hook
const { skuPopupRef, skuText, showSku, skuData, skuMode, openSkuPopup } = useSkuPopup();

// 采用商品详情页弹出层 hook
const { popupRef, popupName, openPopup, addressPanelRef } = useGoodPopup();

// 获取路由参数
const props = defineProps<{ id: string }>();

// 商品详细数据
const goodDetail = ref<GoodsResult>();

// 当前商品大图下标
const currentPictureIndex = ref(0);

// 获取商品详细信息
const getGoodDetailById = async (id: string) => {
  const response = await getGoodDetailByIdAPI(id).request;
  goodDetail.value = response.result;
  // 设置默认收货地址
  if (!addressStore.selectedAddress) addressStore.setSelectedAddress(response.result.userAddresses?.find(a => a.isDefault));
  // 提取sku信息
  {
    const { id, name } = response.result;
    skuData.value = {
      _id: id, name,
      goods_thumb: response.result.mainPictures[0],
      spec_list: response.result.specs.map(i => ({ name: i.name, list: i.values })),
      sku_list: response.result.skus.map(i => ({
        _id: i.id,
        goods_id: id,
        goods_name: name,
        image: i.picture,
        price: i.price * 100,
        stock: i.inventory,
        sku_name_arr: i.specs.map(s => s.valueName),
      })),
    };
  }
};

//商品大图预览事件
const picturePreview = (url: string) => {
  uni.previewImage({ current: url, urls: goodDetail.value!.mainPictures });
};

// 商品加入购物车
const onAddCart = async (e: SkuPopupEvent) => {
  // 检验是否登录
  if (!memberStore.profile) {
    return uni.navigateTo({ url: '/pages/login/login' });
  }
  const { _id, buy_num } = e;
  await postCartAPI({ skuId: _id, count: buy_num }).request;
  uni.showToast({ icon: 'success', title: '已加入购物车！', success: () => showSku.value = false });
};

// 立即购买，生成订单
const onBuyNow = (e: SkuPopupEvent) => {
  // 判断是否已登录
  if (!memberStore.profile) {
    uni.navigateTo({ url: '/pages/login/login', success: () => uni.showToast({ icon: 'none', title: '请先登录！' }) });
  } else {
    // 读取商品id、数量
    const { _id, buy_num } = e;
    uni.navigateTo({ url: `/pagesOrder/create/create?skuId=${_id}&count=${buy_num}${addressStore.selectedAddress ? `&addressId=${addressStore.selectedAddress.id}` : ''}` });
  }
};

onShow(async () => {
  try {
    await getGoodDetailById(props.id);
  }
  catch (e) {
    uni.showToast({ icon: 'none', title: '当前网络状况不佳，请稍后重试！' });
  }
});
</script>

<template>
  <template v-if="goodDetail">
    <scroll-view class="viewport" scroll-y :show-scrollbar="false">
      <!-- 基本信息 -->
      <view class="goods">
        <!-- 商品主图 -->
        <view class="preview">
          <swiper class="image" circular @change="({ detail }) => currentPictureIndex = detail.current">
            <swiper-item v-for="picture in goodDetail?.mainPictures" :key="picture">
              <image class="preview-image" @tap="picturePreview(picture)" mode="aspectFill" :src="picture" />
            </swiper-item>
          </swiper>
          <view class="indicator">
            <text class="current">{{ currentPictureIndex + 1 }}</text>
            <text class="split">/</text>
            <text class="total">{{ goodDetail?.mainPictures.length }}</text>
          </view>
        </view>
        <!-- 商品简介 -->
        <view class="meta">
          <view class="price">
            <text class="symbol">￥</text>
            <text class="number">{{ goodDetail?.price }}</text>
          </view>
          <view class="name ellipis">{{ goodDetail?.name }}</view>
          <view class="desc">{{ goodDetail?.desc }}</view>
        </view>
        <!-- 操作面板 -->
        <view class="action">
          <view class="item arrow" @tap="openSkuPopup(1)">
            <text class="label">选择</text>
            <text class="text ellipsis">{{ skuText }}</text>
          </view>
          <view class="item arrow" @tap="openPopup('address')">
            <text class="label">送至</text>
            <text class="text ellipsis">{{ addressStore.selectedAddressText || '请选择收货地址' }}</text>
          </view>
          <view class="item arrow" @tap="openPopup('service')">
            <text class="label">服务</text>
            <text class="text ellipsis">免费包邮 七天无理由退款 极速退款</text>
          </view>
        </view>
        <!-- 商品详情 -->
        <view class="detail panel">
          <view class="title">
            <text>详情</text>
          </view>
          <view class="content">
            <view class="properties">
              <!-- 属性详情 -->
              <view class="item" v-for="property in goodDetail?.details.properties" :key="property.name">
                <text class="label">{{ property.name }}</text>
                <text class="value">{{ property.value }}</text>
              </view>
            </view>
            <!-- 图片详情 -->
            <image class="image-detail" mode="widthFix" v-for="image in goodDetail?.details.pictures" :key="image"
              :src="image" />
          </view>
        </view>
        <!-- 相似推荐 -->
        <view class="similar panel">
          <view class="title">
            <text>相似推荐</text>
          </view>
          <view class="content">
            <navigator class="goods" hover-class="none" v-for="good in goodDetail?.similarProducts" :key="good.id"
              :url="`/pages/good/good?id=${good.id}`">
              <image class="image" mode="aspectFill" :src="good.picture" />
              <view class="name ellipsis">{{ good.name }}</view>
              <view class="price">
                <text class="symbol">￥</text>
                <text class="number">{{ good.price }}</text>
              </view>
            </navigator>
          </view>
        </view>
      </view>
    </scroll-view>
    <!-- 工具栏 -->
    <view class="toolbar" :style="{ paddingBottom: `${safeAreaInsets?.bottom || 0}px` }">
      <view class="icons">
        <button class="icons-button">
          <text class="icon-heart"></text>收藏
        </button>
        <button class="icons-button" open-type="contact">
          <text class="icon-handset"></text>客服
        </button>
        <navigator class="icons-button" url="/pages/cart/cart-page">
          <text class="icon-cart"></text>购物车
        </navigator>
      </view>
      <view class="buttons">
        <view class="addcart" @tap="openSkuPopup(2)">加入购物车</view>
        <view class="buynow" @tap="openSkuPopup(3)">立即购买</view>
      </view>
    </view>
    <!-- 弹出层 -->
    <uni-popup ref="popupRef" type="bottom" background-color="#fff">
      <AddressPanel ref="addressPanelRef" v-show="popupName === 'address'" :address="goodDetail?.userAddresses"
        @close="popupRef?.close!()" />
      <ServicePanel v-show="popupName === 'service'" @close="popupRef?.close!()" />
    </uni-popup>
    <!-- sku组件 -->
    <vk-data-goods-sku-popup ref="skuPopupRef" v-model="showSku" :localdata="skuData" :mode="skuMode"
      @add-cart="onAddCart" @buy-now="onBuyNow" />
  </template>
  <GoodSkeleton v-else />
</template>

<style lang="scss">
.viewport {
  width: 100vw;
  height: 100vh;
  background-color: #f4f4f4;
}

.panel {
  margin-top: 20rpx;
  background-color: #fff;

  .title {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 90rpx;
    line-height: 1;
    padding: 30rpx 60rpx 30rpx 6rpx;
    position: relative;

    text {
      padding-left: 10rpx;
      font-size: 28rpx;
      color: #333;
      font-weight: 600;
      border-left: 4rpx solid #27ba9b;
    }

    navigator {
      font-size: 24rpx;
      color: #666;
    }
  }
}

.arrow {
  &::after {
    position: absolute;
    top: 50%;
    right: 30rpx;
    content: '\e6c2';
    color: #ccc;
    font-family: 'erabbit' !important;
    font-size: 32rpx;
    transform: translateY(-50%);
  }
}

/* 商品信息 */
.goods {
  background-color: #fff;

  .preview {
    height: 750rpx;
    position: relative;

    .image {
      width: 750rpx;
      height: 750rpx;

      .preview-image {
        width: 100%;
        height: 100%;
      }
    }

    .indicator {
      height: 40rpx;
      padding: 0 24rpx;
      line-height: 40rpx;
      border-radius: 30rpx;
      color: #fff;
      font-family: Arial, Helvetica, sans-serif;
      background-color: rgba(0, 0, 0, 0.3);
      position: absolute;
      bottom: 30rpx;
      right: 30rpx;

      .current {
        font-size: 26rpx;
      }

      .split {
        font-size: 24rpx;
        margin: 0 1rpx 0 2rpx;
      }

      .total {
        font-size: 24rpx;
      }
    }
  }

  .meta {
    position: relative;
    border-bottom: 1rpx solid #eaeaea;

    .price {
      height: 130rpx;
      padding: 25rpx 30rpx 0;
      color: #fff;
      font-size: 34rpx;
      box-sizing: border-box;
      background-color: #35c8a9;
    }

    .number {
      font-size: 56rpx;
    }

    .brand {
      width: 160rpx;
      height: 80rpx;
      overflow: hidden;
      position: absolute;
      top: 26rpx;
      right: 30rpx;
    }

    .name {
      max-height: 88rpx;
      line-height: 1.4;
      margin: 20rpx;
      font-size: 32rpx;
      color: #333;
    }

    .desc {
      line-height: 1;
      padding: 0 20rpx 30rpx;
      font-size: 24rpx;
      color: #cf4444;
    }
  }

  .action {
    padding-left: 20rpx;

    .item {
      height: 90rpx;
      padding-right: 60rpx;
      border-bottom: 1rpx solid #eaeaea;
      font-size: 26rpx;
      color: #333;
      position: relative;
      display: flex;
      align-items: center;

      &:last-child {
        border-bottom: 0 none;
      }
    }

    .label {
      width: 60rpx;
      color: #898b94;
      margin: 0 16rpx 0 10rpx;
    }

    .text {
      flex: 1;
      -webkit-line-clamp: 1;
    }
  }
}

/* 商品详情 */
.detail {
  padding-left: 20rpx;

  .content {
    margin-left: -20rpx;

    .image {
      width: 100%;
    }
  }

  .properties {
    padding: 0 20rpx;
    margin-bottom: 30rpx;

    .item {
      display: flex;
      line-height: 2;
      padding: 10rpx;
      font-size: 26rpx;
      color: #333;
      border-bottom: 1rpx dashed #ccc;
    }

    .label {
      width: 200rpx;
    }

    .value {
      flex: 1;
    }
  }

  .image-detail {
    width: 100%;
  }
}

/* 同类推荐 */
.similar {
  .content {
    padding-bottom: 200rpx;
    background-color: #f4f4f4;
    display: flex;
    justify-content: space-evenly;
    flex-wrap: wrap;

    .goods {
      width: 340rpx;
      padding: 24rpx 20rpx 20rpx;
      margin-top: 20rpx;
      border-radius: 10rpx;
      background-color: #fff;
    }

    .image {
      width: 300rpx;
      height: 260rpx;
    }

    .name {
      height: 80rpx;
      margin: 10rpx 0;
      font-size: 26rpx;
      color: #262626;
    }

    .price {
      line-height: 1;
      font-size: 20rpx;
      color: #cf4444;
    }

    .number {
      font-size: 26rpx;
      margin-left: 2rpx;
    }
  }

  navigator {
    &:nth-child(even) {
      margin-right: 0;
    }
  }
}

/* 底部工具栏 */
.toolbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  background-color: #fff;
  height: 100rpx;
  padding: 0 20rpx var(--window-bottom);
  border-top: 1rpx solid #eaeaea;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-sizing: content-box;

  .buttons {
    display: flex;

    &>view {
      width: 220rpx;
      text-align: center;
      line-height: 72rpx;
      font-size: 26rpx;
      color: #fff;
      border-radius: 72rpx;
    }

    .addcart {
      background-color: #ffa868;
    }

    .buynow,
    .payment {
      background-color: #27ba9b;
      margin-left: 20rpx;
    }
  }

  .icons {
    padding-right: 10rpx;
    display: flex;
    align-items: center;
    flex: 1;

    .icons-button {
      flex: 1;
      text-align: center;
      line-height: 1.4;
      padding: 0;
      margin: 0;
      border-radius: 0;
      font-size: 20rpx;
      color: #333;
      background-color: #fff;

      &::after {
        border: none;
      }
    }

    text {
      display: block;
      font-size: 34rpx;
    }
  }
}
</style>